package com.fqcar.fqdf.ui;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ZoomControls;

import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.model.LatLng;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.engine.cache.MemorySizeCalculator;
import com.fqcar.fqdf.core.BaseRequestActivity;
import com.fqcar.fqdf.core.cache.BitmapDescriptorResource;
import com.fqcar.fqdf.core.cache.LruBitmapDescriptorCache;
import com.fqdf.framework.android.activity.holder.BaseOverlayHolder;
import com.fqdf.framework.android.util.AndroidUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;

public class MapWithCacheActivity extends BaseRequestActivity {

    private final static String THREAD_NAME = "mythread";

    private final static String DEFAULT_MAP_SETTING = "map_style_json.json";

    private MyThreadHandler uiHandler;
    private MyThreadHandler threadHandler;
    private HandlerThread handlerThread;
    private LruBitmapDescriptorCache lruBitmapDescriptorCache;

    protected static final float MAP_ZOOM_DEFAULT = 17.0f;

    protected MapView mMapView;
    protected BaiduMap mBaiduMap;

    @Override
    protected void onResume() {
        super.onResume();
        if (mMapView != null) {
            mMapView.onResume();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mMapView != null) {
            mMapView.onPause();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setMapCustomFile(this);
        initHandler();
    }

    @Override
    protected void onStop() {
        super.onStop();
        getLruBitmapDescriptorCache().clearMemory();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mMapView != null) {
            mMapView.onDestroy();
        }
        clearOverlay();
        closeHandleThread();
    }

    /**
     * 清楚overlay
     */
    public void clearOverlay() {
        mBaiduMap.clear();
    }

    private void initHandler() {
        if (uiHandler == null) {
            uiHandler = new MyThreadHandler(this, getMainLooper());
        }
        // 先进行退出判断
        closeHandleThread();
        // 开启新的handlerThread
        handlerThread = new HandlerThread(THREAD_NAME);
        handlerThread.start();
        threadHandler = new MyThreadHandler(this, handlerThread.getLooper());
    }

    /**
     * 关闭handlerthread
     */
    private void closeHandleThread() {
        if (handlerThread != null) {
            if (AndroidUtils.isSupportVersion(18)) {
                handlerThread.quitSafely();
            } else {
                handlerThread.quit();
            }
        }
    }

    /**
     * 获取处理线程的handler
     *
     * @return
     */
    public MyThreadHandler getThreadHandler() {
        return threadHandler;
    }

    /**
     * 获取处理ui的handler
     *
     * @return
     */
    public MyThreadHandler getUiHandler() {
        return uiHandler;
    }

    /**
     * 初始化地图
     *
     * @param mapView
     */
    protected void initMap(MapView mapView) {
        mMapView = mapView;
        mMapView.showScaleControl(false);//不显示比例尺
        mMapView.showZoomControls(false);//不显示缩放控件
        mBaiduMap = mapView.getMap();
        mBaiduMap.getUiSettings().setRotateGesturesEnabled(false);//禁止地图旋转手势
        mBaiduMap.getUiSettings().setOverlookingGesturesEnabled(false);//设置是否允许俯视手势

        // 隐藏logo
        View child = mMapView.getChildAt(1);
        if (child != null && (child instanceof ImageView || child instanceof ZoomControls)){
            child.setVisibility(View.INVISIBLE);
        }
//        mMapView.setMapCustomEnable(true);

    }

    /**
     * 获取百度地图的baidumap对象
     *
     * @return
     */
    public BaiduMap getBaiduMap() {
        return mBaiduMap;
    }

    /**
     * 获取百度地图mapview对象
     *
     * @return
     */
    public MapView getMapView() {
        return mMapView;
    }

    /**
     * 获取lru缓存
     *
     * @return
     */
    protected LruBitmapDescriptorCache getLruBitmapDescriptorCache() {
        if (lruBitmapDescriptorCache == null) {
            MemorySizeCalculator calculator = new MemorySizeCalculator(this);
            lruBitmapDescriptorCache = new LruBitmapDescriptorCache(calculator.getMemoryCacheSize());
        }
        return lruBitmapDescriptorCache;
    }

    /**
     * bitmap放入缓存
     *
     * @param key      key值
     * @param resource 存入缓存中的bitmapdescriptor对象
     */
    protected void putBitmapDescriptorToCache(Key key, BitmapDescriptor resource) {
        getLruBitmapDescriptorCache().put(key, BitmapDescriptorResource.obtain(resource));
    }

    /**
     * 从缓存中获取bitmapdescriptor对象
     *
     * @param key key值
     * @return 存入缓存的bitmapdescriptor对象，如果不存在对应的缓存的话，则返回null
     */
    protected BitmapDescriptor getBitmapDescriptorFromCache(Key key) {
        BitmapDescriptor bitmapDescriptor;
        if (getLruBitmapDescriptorCache().contains(key)) {
            bitmapDescriptor = getLruBitmapDescriptorCache().get(key).get();
            if (bitmapDescriptor.getBitmap() != null && !bitmapDescriptor.getBitmap().isRecycled()) {
                return bitmapDescriptor;
            }
        }

        return null;
    }

    /**
     * 从缓存中获取bitmapdescriptor对象 如果缓存中不存在对应的值的话，会把view转化成为bitmapdescriptor值并存入缓存以及返回
     *
     * @param key  key值
     * @param view 不存在缓存情况下，需要view转化bitmapdescriptor的对象
     * @return
     */
    public BitmapDescriptor getBitmapDescriptorFromCache(Key key, View view) {
        BitmapDescriptor bitmapDescriptor = getBitmapDescriptorFromCache(key);
        if (bitmapDescriptor == null) {
            bitmapDescriptor = convViewToBitmapDescriptor(view);
            getLruBitmapDescriptorCache().put(key, BitmapDescriptorResource.obtain(bitmapDescriptor));
        }
        return bitmapDescriptor;
    }

    public BitmapDescriptor getBitmapDescriptorFromCache(Key key, BaseOverlayHolder holderView) {
        return getBitmapDescriptorFromCache(key, holderView.getHolderView());
    }

    /**
     * 从缓存中获取bitmapdescriptor对象，如果缓存中不存在对应的值的话，会把viewRes转化成为bitmapdescriptor值并存入缓存以及返回
     *
     * @param key
     * @param viewRes
     * @return
     */
    protected BitmapDescriptor getBitmapDescriptorFromCache(Key key, int viewRes) {
        BitmapDescriptor bitmapDescriptor = getBitmapDescriptorFromCache(key);
        if (bitmapDescriptor == null) {
            bitmapDescriptor = convViewToBitmapDescriptor(viewRes);
            getLruBitmapDescriptorCache().put(key, BitmapDescriptorResource.obtain(bitmapDescriptor));
        }
        return bitmapDescriptor;
    }

    /**
     * 转化view成为bitmapdescriptor
     *
     * @param view overlay对应的view
     * @return
     */
    protected BitmapDescriptor convViewToBitmapDescriptor(View view) {

        Log.e("convViewToBitmap",view+"");

        BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromView(view);

        Log.e("convViewToBitmap bitmap",bitmapDescriptor+"");

        return bitmapDescriptor;
    }

    protected BitmapDescriptor convViewToBitmapDescriptor(int viewRes) {

        BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromResource(viewRes);
        return bitmapDescriptor;
    }

    public static class MyThreadHandler extends Handler {

        WeakReference<MapWithCacheActivity> mActivity;

        public MyThreadHandler(MapWithCacheActivity activity, Looper looper) {
            super(looper);
            mActivity = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mActivity != null && mActivity.get() != null) {
                if (!mActivity.get().lifeCycleIsDestroy() && msg.getCallback() != null) {
                    msg.getCallback().run();
                }
            }
        }
    }

    /**
     * 更改地图视图
     *
     * @param lat
     * @param lon
     * @param zoom
     */
    protected void changePositionAndZoom(double lat, double lon, float zoom) {
        LatLng point = new LatLng(lat, lon);
        MapStatus mMapStatus = new MapStatus.Builder()
                .target(point)
                .zoom(zoom)
                .build();
        //定义MapStatusUpdate对象，以便描述地图状态将要发生的变化
        MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
        //改变地图状态
        mBaiduMap.animateMapStatus(mMapStatusUpdate);
    }

    /**
     * 更改地图视图
     *
     * @param lat
     * @param lon
     */
    protected void changePosition(double lat, double lon) {

        changePositionAndZoom(lat, lon, mBaiduMap.getMapStatus().zoom);
    }

    /**
     * 获取当前地图的缩放级别
     *
     * @return
     */
    protected float getCurZoom() {
        return mBaiduMap.getMapStatus().zoom;
    }

    /**
     * 根据当前点击的marker进行创建y轴偏移量
     *
     * @param marker 要进行显示infowindow的marker
     * @param view   infowindow的内容
     */
    protected InfoWindow createInfoWindow(Marker marker, View view) {

        //创建InfoWindow , 传入 view， 地理坐标， y 轴偏移量
        InfoWindow mInfoWindow = new InfoWindow(view, marker.getPosition(), (int) (-marker.getIcon().getBitmap().getHeight() * 0.78));
        return mInfoWindow;
    }

    // 设置个性化地图config文件路径
    private void setMapCustomFile(Context context) {

        String desFile = null;
        FileOutputStream out = null;
        InputStream inputStream = null;
        try {
            inputStream = context.getAssets()
                    .open(DEFAULT_MAP_SETTING);
            byte[] b = new byte[inputStream.available()];
            inputStream.read(b);

            String moduleName = context.getFilesDir().getAbsolutePath();
            File f = new File(moduleName + File.separator + DEFAULT_MAP_SETTING);
            if (f.exists()) {
                f.delete();
            }
            f.createNewFile();
            out = new FileOutputStream(f);
            out.write(b);
            desFile = f.getAbsolutePath();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (desFile != null) {
            MapView.setCustomMapStylePath(desFile);
        }
    }
}
